package com.ccteam.shared.domain.search

import android.support.v4.media.MediaMetadataCompat
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.map
import com.ccteam.fluidmusic.fluidmusic.common.MusicServiceConnectionFlow
import com.ccteam.fluidmusic.fluidmusic.common.utils.MediaIDHelper
import com.ccteam.fluidmusic.fluidmusic.media.extensions.*
import com.ccteam.model.music.BITRATE_NO
import com.ccteam.model.music.MusicVO
import com.ccteam.shared.api.SearchDataSource
import com.ccteam.shared.data.search.HomeSearchMusicPagingSource
import com.ccteam.shared.domain.PagingUseCase
import com.ccteam.shared.result.artist.ArtistInfoData
import com.ccteam.shared.result.music.DefaultMusicItem
import com.ccteam.shared.utils.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import javax.inject.Inject


/**
 * @author Xiaoc
 * @since 2021/3/16
 *
 * 搜索歌曲Domain层
 * 传入[Pair<String,Boolean>] 歌曲名 和 是否仅搜索
 * 如果是仅搜索，不会将媒体数据添加到BrowseTree中
 * 返回[DefaultMusicItem] 歌曲信息
 */
class HomeSearchMusicDataUseCase @Inject constructor(
    private val searchDataSource: SearchDataSource,
    private val musicServiceConnectionFlow: MusicServiceConnectionFlow
) : PagingUseCase<Pair<String?, Boolean>, DefaultMusicItem>(
    Dispatchers.IO
) {

    /**
     * 缓存MusicVO对象，方便直接添加到播放列表时使用
     */
//    val musicCacheList: MutableMap<String, SearchMoreInfoData> = mutableMapOf()

    override fun execute(parameters: Pair<String?, Boolean>): Flow<PagingData<DefaultMusicItem>> {
        val (searchKey, isOnlySearch) = parameters
        if (searchKey.isNullOrEmpty()) {
            return flowOf(PagingData.empty())
        }
        return if (isOnlySearch) {
            Pager(
                PagingConfig(pageSize = 15, initialLoadSize = 15)
            ) {
                HomeSearchMusicPagingSource(searchKey, searchDataSource)
            }.flow.map { pagingData ->
                pagingData.map {
                    DefaultMusicItem(
                        it.id,
                        it.name,
                        it.artists,
                        emptyList(),
                        EMPTY_STRING,
                        it.imgUrl + ALBUM_QUALITY,
                        BITRATE_NO,
                        true,
                        NO_PLAYING
                    )
                }
            }
        } else {
            Pager(
                PagingConfig(pageSize = 15, initialLoadSize = 15)
            ) {
                HomeSearchMusicPagingSource(searchKey, searchDataSource)
            }.flow.map { pagingData ->
                pagingData.map {
                    transformToDefaultMusicItem(it)
                }
            }
        }
    }

    private fun transformToDefaultMusicItem(musicVO: MusicVO): DefaultMusicItem {

        /**
         * 分割成ArtistInfoData类型，其中含有歌手信息
         */
        val artistsArray = musicVO.artists.split(ARTIST_SEPARATOR)
        val artistInfo = if (artistsArray.size == musicVO.artistsId.size) {
            artistsArray.mapIndexed { index, artistName ->
                ArtistInfoData(musicVO.artistsId[index], artistName)
            }
        } else {
            emptyList()
        }
        // 如果当前音乐没有音源，则不加入到其中
        if(musicVO.maxBitrate != BITRATE_NO && !musicVO.url.isNullOrEmpty()){
            musicServiceConnectionFlow.addOnlineMusicItem(MediaIDHelper.ONLINE_MEDIA_SEARCH,
                MediaMetadataCompat.Builder().apply {
                    id = musicVO.id
                    duration = musicVO.duration
                    title = musicVO.name
                    displayTitle = musicVO.name
                    album = musicVO.albumName
                    displaySubtitle = musicVO.albumName
                    displayDescription = musicVO.artists
                    artist = musicVO.artists
                    albumId = musicVO.albumId
                    trackNumber = musicVO.track.toLong()
                    mediaUri = musicVO.url
                    albumArtUri = musicVO.imgUrl + ALBUM_QUALITY
                    displayIconUri = musicVO.imgUrl + ALBUM_QUALITY
                }.build())
        }

        return DefaultMusicItem(
            musicVO.id,
            musicVO.name,
            musicVO.artists,
            artistInfo,
            musicVO.albumId,
            musicVO.imgUrl + ALBUM_QUALITY,
            musicVO.maxBitrate,
            playable = !musicVO.url.isNullOrEmpty(),
            musicServiceConnectionFlow.nowPlaying.value.getPlaybackStatus(musicVO.id)
        )
    }
}